// ==UserScript==
// @name Shack-lol
// @namespace http://www.lmnopc.com/greasemonkey/
// @description Adds [lol] links to posts
// @include http://shacknews.com/*
// @include http://*.shacknews.com/*
// @include http://fileshack.com/*
// @include http://*.fileshack.com/*
// @include http://shackvideo.com/*
// @include http://*.shackvideo.com/*
// @include http://shackvideos.com/*
// @include http://*.shackvideos.com/*
// @exclude http://bananas.shacknews.com/*
// @exclude http://*.gmodules.com/*
// ==/UserScript==
/*
	------------------------------------------------------------

	Shack [lol]
	Author: Thom Wetzel - www.lmnopc.com
	(C)2007-2009 Thom Wetzel

	------------------------------------------------------------

	REVISIONS:

	2007-01-26
	- Initial Release

	.
	.
	.
	
	2009-05-13
		* ported to chrome
	2009-10-13
		* Updated to work with Chrome Extension r2    
    
*/

if (script_enabled('Lolscript') == 'true') 
{
    var myDomain = 'lmnopc.com';
    var version = 20090513;

    // grab start time of script
    var benchmarkTimer = null;
    var scriptStartTime = getTime();

    function tw_log(str) {
        GM_log(str); 
    }
    function getTime() { benchmarkTimer = new Date(); return benchmarkTimer.getTime(); }
    function stripHtml(html) { return String(html).replace(/(<([^>]+)>)/ig, ''); }

    function parseQueryString() 
	 {
        // Return object with query string variables.
        // from http://www.ektron.com/developers/ewebeditprokb.cfm?id=365
        var objQuery = new Object();
        var strQuery = location.search.substring(1);
        var aryQuery = strQuery.split("&");
        var pair = [];
        for (var i = 0; i < aryQuery.length; i++) {
            pair = aryQuery[i].split("=");
            if (pair.length == 2) {
                objQuery[unescape(pair[0])] = unescape(pair[1]);
            }
        }
        return objQuery;
    }

    function removeClassName(needle, haystack) 
	 {
        var straws = haystack.split(' ');
        var idx = straws.indexOf(needle);
        if (idx == -1) 
		  {
            return haystack;
        }
        straws.splice(idx, 1);
        return straws.join(' ');
    }

    function findUsername() 
	 {
        return stripHtml(getElementByClassName(document.getElementById('masthead'), 'a', 'username').innerHTML);
    }

    // ThomW: I took getElementsByClassName and stripped it down to just what's needed by this script
    function getElementByClassName(oElm, strTagName, strClassName) 
	 {
        var arrElements = oElm.getElementsByTagName(strTagName);
        for (var i = 0; i < arrElements.length; i++) 
		  {
            if (arrElements[i].className.indexOf(strClassName) == 0) 
				{
                return arrElements[i];
            }
        }
    }

    // shackLol functions
    function installLolButton(threadIdList) 
	 {
        var dbg = false;

        var startTime = getTime();

        var msg = '';

        // this makes the script run on the right document when called from the iframe
        if (window != top) 
		  {
            doc = top.document;
        }
        else 
		  {
            doc = document;
        }

        threadIdList = String(threadIdList).split(',');
        var numThreads = threadIdList.length;

        for (var i = 0; i < numThreads; i++) 
		  {
            var threadId = threadIdList[i];
            
            // GM_log('installLolButton: ' + threadId);
				
				if (doc.getElementById('lolTools_' + threadId) != null)
				{
					continue; 
				} 

            // find threadId
            var t = doc.getElementById('item_' + threadId);
            if (!t) 
				{
                if (dbg) { tw_log('COULD NOT FIND root_' + threadId); }
                return false;
            }

            // find div.postmeta
            var pm = getElementByClassName(t, 'span', 'author');
            if (!pm) 
				{
                if (dbg) { tw_log('getElementsByClassName could not locate span.author'); }
                return false;
            }

				var d = doc.createElement('div');
				d.id = 'lolTools_' + threadId; 
				d.setAttribute('style', 'display: inline; float: none; padding-left: 10px; font-size: 14px;');
				
				var buttonHtml = ''; 
				buttonHtml += ' [<a id="lol' + threadId + '" onClick="lolThread(event)" style="cursor: pointer; color: #f80; padding: 0 0.25em; text-decoration: underline;">lol</a>]'; 
				buttonHtml += ' [<a id="inf' + threadId + '" onClick="lolThread(event)" style="cursor: pointer; color: #09c; padding: 0 0.25em; text-decoration: underline;">inf</a>]';
				buttonHtml += ' [<a id="unf' + threadId + '" onClick="lolThread(event)" style="cursor: pointer; color: #f00; padding: 0 0.25em; text-decoration: underline;">unf</a>]';
				buttonHtml += ' [<a id="tag' + threadId + '" onClick="lolThread(event)" style="cursor: pointer; color: #7b2; padding: 0 0.25em; text-decoration: underline;">tag</a>]';
				buttonHtml += ' [<a id="wtf' + threadId + '" onClick="lolThread(event)" style="cursor: pointer; color: #C000C0; padding: 0 0.25em; text-decoration: underline;">wtf</a>]';
				
				// XOXO PANCAKE HUMPER XOXO
				// buttonHtml += ' [<a id="tth' + threadId + '" onClick="lolThread(event)" style="cursor: pointer; color: #fbb; padding: 0 0.25em; text-decoration: underline;">tth</a>]';
				
				d.innerHTML = buttonHtml; 

            // add d to pm
            pm.appendChild(d);
        }
    }

    function getModeration(threadId) 
	 {
        var modTags = new Array('fpmod_offtopic', 'fpmod_nws', 'fpmod_stupid', 'fpmod_informative', 'fpmod_political');

        var liItem = document.getElementById('item_' + threadId);

        var className = liItem.getElementsByTagName('div')[0].className;

        className = className.split(' ');

        for (var i = 0; i < modTags.length; i++) 
		  {
            for (var j = 0; j < className.length; j++) 
				{
                if (modTags[i] == className[j]) 
					 {
                    return modTags[i];
                }
            }
        }

        return '';
    }


    function lolThread2(thread, tag) 
	 {
        var userName;
        var moderation = '';

        if (tag == null) { tag = 'lol'; }

        if (String(location.href).indexOf('/greasemonkey/shacklol/') != -1) {
            userName = lol_username;
            if (String(userName).length == 0) {
                alert("I don't know who you are, man!  You have to log into the Shack then [lol] a post there before you can [lol] them here. Sorry.");
                return;
            }
        }
        else {
            // find the user
            var userName = findUsername();
            if (!userName) 
				{
                alert('You have to be logged in to Shacknews to +lol a post');
                return;
            }


            lol_username = userName;

            // Scrape the post's current moderation from the page (this is only done on Shacknews.com obviously) 
            moderation = getModeration(thread);
            if (moderation.length) 
				{
                moderation = '&moderation=' + moderation;
            }
        }

        //
        var addr = 'http://' + myDomain + '/greasemonkey/shacklol/report.php?who=' + userName + '&what=' + thread + '&tag=' + tag + '&version=' + version + moderation;
        var tag_id = tag + thread;
        //GM_log(addr);
        request = new XMLHttpRequest();
        request.onreadystatechange = function() 
		  {
            var result = this;
            
            GM_log(result);
            
            if (result.readyState == 4) { // for now assume success && result.status == 200) {
                try {
                    var taggd = '*';
                    for (i = 0; i < tag.length; i++) {
                        taggd += ' ' + tag[i].toUpperCase() + ' ';
                    }
                    taggd += ' \' D *';

                    var objLol = document.getElementById(tag_id);
                    objLol.setAttribute('onclick', '');
                    objLol.innerHTML = '<a href="http://' + myDomain + '/greasemonkey/shacklol/?user=' + encodeURIComponent(findUsername()) + '" style="color: #f00;">' + taggd + '</a>';

                }
                catch (e) {
                    alert('+' + tag + ' failed');
                }
            }
        }
        request.open("GET", addr, true);
        request.setRequestHeader("Accept", "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
        request.send(null);
    }
    
    function iframeOnLoad()
    {
			// SO IT'S COME TO THIS 
			//
			// Since Chrome stopped firing extensions on iframe loads, I'm now
			// watching the iframe's onload event and waiting 250ms before 
			// attempting to reinstall the lol buttons. Clunky but whatever.   
						
			setTimeout(function() 
			{ 
				// find all the fullposts on the page
				var items = document.evaluate("//div[contains(@class, 'fullpost')]/..", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
				var idList = '';
				for (item = null, i = 0; item = items.snapshotItem(i); i++) 
				{
					idList += idList.length ? ',' : '';
					idList += item.id.substr(5);
				}
				installLolButton(idList);
			}, 100); 
	}


    /* MAIN
    */

    // Since this is used by several cases I'm going to add this to every page, even where it's not needed.
    if (typeof(lolThread) == 'undefined') 
	 {
        lolThread = function(event) 
		  {
            var tag = event.target.getAttribute('id').substr(0, 3);
            var threadId = event.target.getAttribute('id').substr(3);
            window.setTimeout(function() 
				{
                lolThread2(threadId, tag);
            }, 1);
        }
    }
    
    //
    // PROFILE PAGE
    //
    if ((String(location.href).indexOf('profile.x?person') != -1) ||
			(String(location.href).indexOf('shacknews.com/profile/') != -1) ||
			(String(location.href).indexOf('shacknews.com/library/') != -1) ||
			(String(location.href).indexOf('shacknews.com/librarywanted/') != -1) ||
			(String(location.href).indexOf('shacknews.com/settings/') != -1)) 
		{

        var person = '';

        // Supports old-style profile.x URLs in case someone ends up on bizarro shack
        if (String(location.href).indexOf('profile.x?person') != -1) 
		  {
            // read the query string
            var qs = parseQueryString();
            person = qs['person'];
        }
        // new-style profile URL
        else 
		  {
            var arr = String(location.href).split('/');
            if (arr.length == 5) 
				{
                person = unescape(arr[4]);
            }
        }

        if (person.length) 
		  {
            // create the [lol] link next to the user's name
            var smLink = document.createElement('a');
            smLink.style.color = 'white';
            smLink.innerHTML = ' [<span style="color: orange; font-size: inherit; font-weight: bold; margin: 0; padding: 0 4px;">lol</span>]';
            smLink.setAttribute('href', 'http://' + myDomain + '/greasemonkey/shacklol/user.php?authoredby=' + escape(person));
            smLink.setAttribute('target', '_blank');
            document.getElementsByTagName('h3')[0].appendChild(smLink);

            // Create the new menu items
            var ulStatus = getElementByClassName(document, 'ul', 'status');

            // Create vanity search link
            var liVS = document.createElement('li');
            liVS.innerHTML = '<a href="http://www.shacknews.com/search.x?type=comments&terms=' + escape(person.replace('_', '')) + '&cs_user=">Vanity Search</a>';
            ulStatus.appendChild(liVS);

            // Create parentAuthor
            var liPA = document.createElement('li');
            liPA.innerHTML = '<a href="http://www.shacknews.com/search.x?type=comments&terms=&cs_user=&cs_parentauthor=' + escape(person) + '&s_type=all">Parent Author</a>';
            ulStatus.appendChild(liPA);
        }
    }

    //
    // LARYN.X
    //
    else if (String(location.href).indexOf('laryn.x') != -1) 
	 {
        if ((typeof(shacklol_show_item_fullpost) == 'undefined') && (typeof(show_item_fullpost) != 'undefined')) 
		  {
            // override standard show_item_fullpost with one that supports this script
            shacklol_show_item_fullpost = show_item_fullpost;
            show_item_fullpost = function(root_id, article_id, fullpost_element) {
                // call original function
                shacklol_show_item_fullpost(root_id, article_id, fullpost_element);

                installLolButton(article_id);
            }
        }
        
        // find all the fullposts on the page
        var items = document.evaluate("//div[contains(@class, 'fullpost')]/..", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
        var idList = '';
        for (item = null, i = 0; item = items.snapshotItem(i); i++) {
            idList += idList.length ? ',' : '';
            idList += item.id.substr(5);
        }
        installLolButton(idList);
        
        // Install event handler on iframe 
        document.getElementById('dom_iframe').addEventListener('load', iframeOnLoad, false); 

        // add link to lol'd above the comments
        var divCommentstools = getElementByClassName(document, 'div', 'commentstools');
        if (divCommentstools != null) {
            var divLol = document.createElement('a');
            divLol.setAttribute('id', 'lol-link');
            // CSS MOVED TO SHACKSCRIPTS.CSS
            divLol.setAttribute('href', 'http://' + myDomain + '/greasemonkey/shacklol/?user=' + encodeURIComponent(findUsername()));
            divLol.setAttribute('title', 'Check out what got the [lol]s');
            divLol.appendChild(document.createTextNode('[ L O L ` d]'));
            divCommentstools.appendChild(divLol);
        }
    }

    //
    // ADD shack[lol] TO THE LIST AT THE TOP OF EVERY PAGE ON THE SHACK
    //
    var ulSites = getElementByClassName(document, 'ul', 'sites');
    if (ulSites != null) 
	 {
        // Remove 'last' from the current 'last' list element
        var liLast = getElementByClassName(ulSites, 'li', 'last');
        if (liLast) 
		  {
            liLast.className = removeClassName('last', liLast.className);
        }

        // Create new li to contain the link to the [lol] page
        var li = document.createElement('li');
        li.className = 'last';
        li.innerHTML = '<a href="http://' + myDomain + '/greasemonkey/shacklol/?user=' + encodeURIComponent(findUsername()) + '">Shack[<span style="color: #f80;">lol</span>]</a>';

        // Add the
        ulSites.appendChild(li);
    }

    // log execution time
    tw_log('lol.js: ' + location.href + ' / ' + (getTime() - scriptStartTime) + 'ms');
}